package detect;

import interfaces.Detect;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import entities.Domain;

public class DetectTypeBlock implements Detect {

	@SuppressWarnings("unused")
	@Override
	public void getInfo(Map<String, Object> obj) {
		Document doc = (Document) obj.get("doc");
		Domain domain = (Domain) obj.get("domain");

		try {
			PrintStream out = new PrintStream(System.out, true, "UTF-8");

			int minItem = 5;
			int minWord = 200;
			String mainSelector = "";
			Element mainElement = null;
			String name = domain.getName();

			Elements elms = doc.select("a");
			List<String> escapeElms = new ArrayList<String>();

			Map<String, List<Element>> selectors = new TreeMap<String, List<Element>>();

			for (Element elm : elms) {
				String href = elm.attr("href");
				if (!href.startsWith("#")
						&& (href.startsWith("/") || href.contains(name))) {
					String selector = getSelector(doc, elm, "");
					List<Element> elements = selectors.get(selector);
					if (elements == null) {
						elements = new ArrayList<Element>();
					}
					elements.add(elm);
					selectors.put(selector, elements);
				}
			}

			for (Map.Entry<String, List<Element>> entry : selectors.entrySet()) {
				try {
					List<Element> els = entry.getValue();
					Element a1 = null;
					Element a2 = null;
					if (els.size() >= minItem) {
						a1 = els.get(0);
						a2 = els.get(1);
						boolean exit = false;
						while (!exit) {
							if (a1.parent() == a2.parent()) {
								exit = true;

								if (mainElement == null) {
									mainElement = a1.parent();
								} else if (mainElement != null
										&& mainElement.text().length() <= a1
												.parent().text().length()) {
									mainElement = a1.parent();
								}

							} else {
								a1 = a1.parent();
								a2 = a2.parent();
							}

						}
					}
				} catch (Exception e) {
					System.out.println(e.getMessage()); 
				}

			}

			if (mainElement != null) {
				String selector = getSelector(doc, mainElement, "");
				double rate = (double) mainElement.text().length() * 100
						/ (double) doc.select("body").text().length();

				domain.setMainContentSelector(selector);
				domain.setRateMainContent(rate);

				if (rate > 60) {

				} else {

				}

			} else {

			}

		} catch (Exception e) {
			// e.printStackTrace();
		}

	}

	private String getSelector(Document doc, Element elmSelector,
			String selector) {

		List<String> blockLevel = new ArrayList<String>(Arrays.asList(
				"address", "address", "ol", "article", "figure", "output",
				"aside", "footer", "p", "audio", "form", "pre", "blockquote",
				"h1", "h2", "h3", "h4", "h5", "h6", "section", "canvas",
				"header", "table", "dd", "hgroup", "tfoot", "div", "hr", "ul",
				"dl", "noscript", "fieldset", "video"));

		String tagName = elmSelector.tagName();
		String id = elmSelector.id();

		if (id != null && !id.isEmpty()
				&& blockLevel.contains(elmSelector.tagName())) {
			return "#" + id + (selector.isEmpty() ? selector : " " + selector);
		}

		if (tagName.equalsIgnoreCase("html")
				|| tagName.equalsIgnoreCase("body") || tagName.equals("head")
				|| tagName.equalsIgnoreCase("footer")
				|| tagName.equalsIgnoreCase("header")) {
			return tagName + (selector.isEmpty() ? selector : " " + selector);
		}

		if (!elmSelector.attr("class").isEmpty()) {
			String[] classList = elmSelector.attr("class").split(" ");
			for (int i = 0; i < classList.length; i++) {
				String selc = "." + classList[i];
				if (doc.select(selc + " " + selector).size() == 1
						&& blockLevel.contains(elmSelector.tagName())) {
					return selc
							+ (selector.isEmpty() ? selector : " " + selector);
				}

				selc = tagName + selc;

				if (doc.select(selc + " " + selector).size() == 1
						&& blockLevel.contains(elmSelector.tagName())) {
					return selc
							+ (selector.isEmpty() ? selector : " " + selector);
				}

				if (doc.select(selc + " " + selector).size() > 0) {
					int index = 0;
					for (Element elm : doc.select(selc + " " + selector)) {
						if (elm == elmSelector) {
							selc = selc + ":eq(" + index + ")";
						}
						index++;
					}
				}

				if (doc.select(selc + " " + selector).size() == 1
						&& blockLevel.contains(elmSelector.tagName())) {
					return selc
							+ (selector.isEmpty() ? selector : " " + selector);
				}
			}

			String selc = tagName;
			for (int i = 0; i < classList.length; i++) {
				selc = selc + "." + classList[i];
			}

			selector = selc + (selector.isEmpty() ? selector : " " + selector);
		}

		if (selector.isEmpty()) {
			selector = tagName;
			Elements elms = elmSelector.parent().select(">" + selector);
			if (elms.size() > 1) {
				for (int i = 0; i < elms.size(); i++) {
					if (elms.get(i) == elmSelector) {
						selector = selector + ":eq(" + i + ")";
					}
				}
			}
		}

		selector = getSelector(doc, elmSelector.parent(), selector);

		return selector;
	}
}
